package com.acme.bankapp.domain.bank.transport;

import com.acme.bankapp.domain.bank.Bank;
import com.acme.bankapp.domain.bank.Client;
import com.acme.bankapp.domain.bank.exception.BadStringToParseClient;
import com.acme.bankapp.domain.bank.exception.ClientExistsException;
import com.acme.bankapp.domain.bank.exception.ConnectionException;
import com.acme.bankapp.domain.bank.exception.TooManyClients;
import com.acme.bankapp.service.bank.BankDataLoaderService;

import java.io.IOException;
import java.net.ServerSocket;

public class ServerStub {

    private static final int port = 7777;
    private Connection connection;
    private Bank bank;

    public ServerStub(Bank bank, Connection connection) {
        if (connection == null)
            throw new IllegalArgumentException("Connection is null");
        if (bank == null)
            throw new IllegalArgumentException("Connection is null");
        this.connection = connection;
        this.bank = bank;
    }

    public void addClient() throws ConnectionException {
        try {
            Client client = BankDataLoaderService.parseString(connection.readLine());
            bank.addClient(client);
            connection.writeLine("OK");
        } catch (BadStringToParseClient | ClientExistsException | TooManyClients e) {
            connection.writeLine("ERROR");
        }
    }

    public void getClient() throws ConnectionException {
        connection.writeLine(String.valueOf(bank.getClientNumber()));
        for (Client c : bank.getClients())
            if (c != null)
                connection.writeLine(BankDataLoaderService.clientToString(c));
    }

    public void mainLoop() {
        try {
            while (true) {
                String cmd = connection.readLine();
                switch (cmd) {
                    case "ADD":
                        addClient();
                        break;
                    case "STAT":
                        getClient();
                        break;
                }
            }
        } catch (Exception e) {
            System.out.println("Client disconnected!");
            e.printStackTrace();
        } finally {
            try {
                connection.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void handleClients(Bank bank) throws IOException {
        ServerSocket ss = new ServerSocket(port);
        while (true) {
            new ServerStub(bank, new NetworkConnection(ss.accept())).mainLoop();
        }
    }
}
